/*
Copyright (C) 2009-2010 Xanadu Development Team

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2
of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

#include "../../server/Channel.h"
#include "Guilds.h"
#include "Guild.h"
#include "GuildMembers.h"
#include "GuildMember.h"
#include "../../server/Map.h"
#include "../../tools/MySQLM.h"
#include "../../tools/PacketCreator.h"
#include "../../server/Player.h"
#include "World.h"
string valstr(int id);

void Guilds::create(Player* player, string guildname) {
	player->giveMesos(-1500000);
	player->setGuildRank(1);
	Guild* guild = new Guild(world, player, guildname);
	player->setGuild(guild);
	player->send(PacketCreator().guildInfo(guild));
	player->send(PacketCreator().addGuildPlayer(guild->getID(), guild->getMembers()->getMember(player->getID())));
	guilds[guild->getID()] = guild;
}

void Guilds::leave(Player* player) {
	Guild* guild = player->getGuild();
	GuildMember* member = guild->getMembers()->getMember(player->getID());
	if (member == 0 || player->getGuildRank() == 1) {
		return;
	}
	guild->getMembers()->send(PacketCreator().guildPlayerLeave(guild->getID(), player->getID(), player->getName()));
	guild->removeMember(player->getID());
	player->setGuild(0);
	player->setGuildRank(5);
}

void Guilds::join(Player* player, int guildid) {
	Guild* guild = getGuild(guildid);
	if (guild == 0 || guild->getMembers()->getPlayersCount() >= guild->getCapacity()) {
		return;
	}
	player->setGuild(guild);
	guild->getMembers()->addMember(player);
	GuildMember* member = guild->getMembers()->getMember(player->getID()); 
	if (member != 0) {
		player->send(PacketCreator().guildInfo(guild));
		guild->getMembers()->send(PacketCreator().addGuildPlayer(guild->getID(), member));
	}
}

void Guilds::invite(Player* player, string name) {
	Player* invited = player->getChannel()->getPlayers()->getPlayerByName(name);
	if (invited == 0 || invited->getGuildInvite() != 0 || invited->getGuild() != 0) {
		return;
	}
	Guild* guild = player->getGuild();
	if (guild->getMembers()->getPlayersCount() >= guild->getCapacity())
		return;
	invited->setGuildInvite(guild->getID());
	invited->send(PacketCreator().inviteGuild(player->getName(), guild->getID()));
}

void Guilds::expel(Player* player, int playerid, string name) {
	Guild* guild = player->getGuild();
	GuildMember* member = guild->getMembers()->getMember(playerid);
	if (member == 0)
		return;
	Player* expelled = guild->getMembers()->getPlayerByID(playerid);
	if (expelled != 0) {
		expelled->setGuild(0);
		expelled->setGuildRank(5);
	} else {
		mysqlpp::Connection::thread_start();
		mysqlpp::Connection* conn = MySQL::getInstance()->getPool()->grab();
		mysqlpp::Query query = conn->query("update characters set guild=0, guildrank=5 where id=" + valstr(playerid));
		query.execute();
		MySQL::getInstance()->getPool()->release(conn);
		mysqlpp::Connection::thread_end();
	}
	guild->removeMember(playerid);
	guild->getMembers()->send(PacketCreator().guildPlayerLeave(guild->getID(), playerid, name, true));
}

void Guilds::removeEmblem(Player *player) {
	player->giveMesos(-1000000);
	Guild* guild = player->getGuild();
	guild->setLogoBG(0);
	guild->setLogoBGColor(0);
	guild->setLogo(0);
	guild->setLogoColor(0);
}

void Guilds::changeRank(Player* player, int rank, int userid) {
	Guild* guild = player->getGuild();
	GuildMember* member = guild->getMembers()->getMember(userid);
	member->setRank(rank);
	Player* changed = guild->getMembers()->getPlayerByID(userid);
	if (changed != 0) {
		changed->setGuildRank(rank);
	}
	guild->getMembers()->send(PacketCreator().changeRank(guild->getID(), userid, rank));
}

void Guilds::increaseCapacity(Player* player) {
	Guild* guild = player->getGuild();
	guild->setCapacity(guild->getCapacity() + 5);
	guild->getMembers()->send(PacketCreator().changeGuildCapacity(guild->getID(), guild->getCapacity()));
	mysqlpp::Connection::thread_start();
	mysqlpp::Connection* conn = MySQL::getInstance()->getPool()->grab();
	mysqlpp::Query query = conn->query("update guilds set capacity=" + valstr(guild->getCapacity()) + " where guildid=" + valstr(guild->getID()));
	query.execute();
	MySQL::getInstance()->getPool()->release(conn);
	mysqlpp::Connection::thread_end();
}

Guild* Guilds::getGuild(int id) {
	mysqlpp::Connection::thread_start();
	mysqlpp::Connection* conn = MySQL::getInstance()->getPool()->grab();
	mysqlpp::Query query = conn->query();
	if (guilds.find(id) == guilds.end()) {
		query << "select * from guilds where guildid=" << id;
		mysqlpp::StoreQueryResult res = query.store();
		if (res.empty()) {
			return 0;
		}
		Guild* guild = new Guild(id);
		guild->setGuildPoints(atoi(res[0][3]));
		guild->setGuildName(string(res[0][4]));
		guild->setCapacity(atoi(res[0][5]));
		guild->setNotice(string(res[0][6]));
		for(int i = 0; i<5; i++) {
			guild->setRank(string(res[0][7+i]), i);
		}
		guild->setLogoBG(atoi(res[0][12]));
		guild->setLogoBGColor(atoi(res[0][13]));
		guild->setLogo(atoi(res[0][14]));
		guild->setLogoColor(atoi(res[0][15]));
		query << "select id, name, job, level, guildrank from characters where guild=" << valstr(id);
		res = query.store();
		for(int i=0; i<(int)res.num_rows(); i++) {
			GuildMember* member = new GuildMember();
			member->setID(atoi(res[i][0].c_str()));
			member->setName(string(res[i][1].c_str()));
			member->setJob(atoi(res[i][2].c_str()));
			member->setLevel(atoi(res[i][3].c_str()));
			member->setRank(atoi(res[i][4].c_str()));
			guild->getMembers()->addMember(member);
		}
		guilds[id] = guild;
	}
	MySQL::getInstance()->getPool()->release(conn);
	mysqlpp::Connection::thread_end();
	return guilds[id];
}

void Guilds::deleteGuild(int gid) {
	guilds[gid]->getMembers()->send(PacketCreator().disbandGuild(gid));
	delete guilds[gid];
	guilds.erase(gid);
}